Dedecms框架漏洞复现⑤
漏洞影响范围
dedecms 5.7.93 - 5.7.96
漏洞分析
DedeCMS v5.7.93在/dede/login. php
文件中增加了登录失败锁功能,以符合相关的Web安全法规。当用户登录失败时,失败消息将写入文件/data/login.data.php
,以记录该用户登录失败的次数。
我们看下login.php
的关键代码,在我们登录的时候并没有验证用户名,就直接写入了文件
这里我们看到,如果我们连续登录失败,会将 $arr_login
在 json_encode
后写入文件/data/login.data.php
中,写入内容有用户名,次数,时间,这里我们就可以通过给用户名赋值恶意代码导致RCE
dedecms
会对进入程序的所有变量进行一次过滤,比如这里的 $userid
,过滤的具体代码位于 /include/common.inc.php
这里对变量使用了addslashes()
函数,按理来说我们写入了';phpinfo();?>
存到文件中之后,会转变成 \';phpinfo();?>
,这样我们的'
就被转义了,就无法闭合之前的单引号。但是这里的问题出在我们的登录信息存到文件中的时候是经过json_encode
的,json_encode
会转义 /\
等字符。
所以最后变成了';phpinfo();?>
-> \';phpinfo();?>
-> \\';phpinfo();?>
这里又将转义字符转义回去了,所以我们的'
也会起到转换的作用,进而闭合,进行RCE
漏洞复现
访问登录页面,然后输入用户名';phpinfo();?>' 我在登录第二次的时候,就看到闪过了
phpinfo的界面 我们发现在网站目录下确实生成了
login.data.php`这个文件
访问一下这个文件
所以POC为
1 | POST /dede/login.php HTTP/1.1 |
修补方法
在 5.7.97
中, login.php
中对应的代码变成了下面这样
此处添加了$res==-1
这个比较,就要求我们登录的用户名必须是经过注册了的,如果不存在,将会直接退出而不会写入文件中
这里修复之后其实还可以进行绕过,详细可以看这篇文章
思考
- 这里由于单引号和双引号的作用,比如我们想执行
whoami
命令,我们就不能使用system('whoami');
这些命令执行的函数了,因为他们写到文件里面之后会变成
system(\\'whoami\\');
,这时候会进行报错,因为我们不能在函数的头尾的单引号上面使用转义。那这样的话,我们有什么办法去使用我们的函数去执行命令呢
这里就可以使用一些ctf中常见的绕过手法了
回答:
①使用反引号 比如
1 | echo `whoami`; |
②chr()
函数+连接符.
1 | system(chr(119) . chr(104) . chr(111) . chr(97) . chr(109) . chr(105)); |
③括号(
绕过
1 | (sy.(st).em)(whoami); |
- 框架中还有没有其他的地方有类似的写法
回答:目前没有发现